<template>
  <div v-if="isVideo" class="video-input gap-col-8">
    <div class="type-switch">
      <div class="switch gap-row-22 font-size-12 font-weight-500 line-height-120 text-background bg-primary">
        {{ videoIndirectorText }}
      </div>
      <div class="font-size-12 font-weight-400 line-height-120 text-graydisabled">{{ recommendSizeText }}</div>
    </div>
    <div class="file" :class="videoDirStyle">
      <label v-if="noUploadFiles" class="reupload pointer">
        <Icon size="54" name="gradientImage"></Icon>
        <span class="font-size-14 font-weight-500 line-height-140 text-primary">{{ $t('content.reUpload') }}</span>
        <input
          type="file"
          accept="video/mp4, video/quicktime, video/x-quicktime, video/mov, video/x-mov, video/avi"
          multiple
          @change="onVideoFile"
        />
      </label>
      <div v-else class="upload-info">
        <video v-show="isCreate && uploadFiles[0].status !== UPLOAD_STATUS.FAIL" ref="video" controls></video>
        <EncryptImage
          v-if="isUpdate && publishParams.slice === VIDEO_SLICE_STATUS.SUCCESS"
          :src="publishParams.imgPath"
          :border-radius="10"
        ></EncryptImage>
        <div
          v-else-if="isUpdate && publishParams.slice === VIDEO_SLICE_STATUS.FAILURE"
          class="slice-mask font-size-14 font-weight-500 lien-height-140 text-primary"
        >
          {{ $t('content.videoSliceFail') }}
        </div>
        <div
          v-else-if="isUpdate && [VIDEO_SLICE_STATUS.PENDING, VIDEO_SLICE_STATUS.SLICING].includes(publishParams.slice)"
          class="slice-mask font-size-14 font-weight-500 lien-height-140"
        >
          {{ $t('content.videoSlicing') }}
        </div>
        <ProgressBar
          v-if="uploadFiles[0].status !== UPLOAD_STATUS.SAVE"
          :upload-progress="uploadFiles[0].progress"
          :upload-status="uploadFiles[0].status"
          :upload-fail-msg="uploadFiles[0].failMsg"
          :progress-msg="uploadFiles[0].progressMsg"
          :padding-large="isHorizontal"
          @reupload="reUploadFile(uploadFiles[0].id)"
        ></ProgressBar>
      </div>
    </div>
    <Icon
      v-if="isCreate && !noUploadFiles && uploadFiles[0].status === UPLOAD_STATUS.DONE"
      name="close"
      class="close pointer"
      size="20"
      @click="removeUploadFile(uploadFiles[0].id)"
    ></Icon>
    <div
      v-if="isCreate && !noUploadFiles && uploadFiles[0].status === UPLOAD_STATUS.UPLOADING"
      class="cancel pointer font-size-14 font-weight-500 lien-height-140"
      @click="cancel(uploadFiles[0].id)"
    >
      {{ $t('common.cancel') }}
    </div>
  </div>
  <div v-if="isImage" class="image-input gap-col-8">
    <div class="type-switch">
      <div class="switch font-size-12 font-weight-500 line-height-120 text-background bg-primary">
        {{ $t('info.media.imageSet') }}
      </div>
    </div>
    <Draggable v-model="uploadFiles" item-key="id" class="image-container gap-row-8" handle=".handle">
      <template #item="{ element, index }">
        <div class="file">
          <img
            v-if="element.result && element.status !== UPLOAD_STATUS.FAIL"
            :src="element.result"
            alt="Post multiple pictures"
          />
          <EncryptImage v-if="element.status === UPLOAD_STATUS.SAVE" :src="element.url"></EncryptImage>
          <ProgressBar
            v-if="element.status !== UPLOAD_STATUS.SAVE"
            :upload-progress="element.progress"
            :upload-status="element.status"
            :upload-fail-msg="element.failMsg"
            @reupload="reUploadFile(element.id)"
          ></ProgressBar>
          <div class="index font-size-10 font-weight-500 line-height-120">
            {{ index + 1 + '/' + uploadFiles.length }}
          </div>
          <Icon name="close" class="close pointer" size="20" @click="removeUploadFile(element.id)"></Icon>
          <Icon name="indicator" class="handle"></Icon>
        </div>
      </template>
      <template #footer>
        <label class="add">
          <input
            ref="input"
            type="file"
            accept="image/jpg, image/jpeg, image/png, image/gif"
            multiple
            @change="onImageFile"
          />
        </label>
      </template>
    </Draggable>
  </div>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import Draggable from 'vuedraggable'
import { storeToRefs } from 'pinia'
import { usePopupDialogStore } from '@/store/popup-dialog'
import { usePublishStore } from '@/store/publish'
import { $t } from '@/i18n'
import EncryptImage from '@/components/multimedia/EncryptImage.vue'
import { UPLOAD_STATUS, VIDEO_SLICE_STATUS } from '@/constant/publish'
import VideoLengthOverlimitError from '@/errors/VideoLengthOverlimitError'
import ProgressBar from './ProgressBar.vue'

const emits = defineEmits(['videoOverlimit', 'uploadFail'])

const publishStore = usePublishStore()
const { onFileInput, uploadFiles, noUploadFiles, isCreate, isUpdate, isVideo, isImage, isHorizontal, isVertical } =
  storeToRefs(publishStore)
const { startUpload, addVideoFile, addImageFile, removeUploadFile, reUploadFile, cancelUpload, publishParams } =
  publishStore

const videoIndirectorText = computed(
  () => (isHorizontal.value ? $t('info.shape.horizontal') : $t('info.shape.vertical')) + $t('info.media.video'),
)
const recommendSizeText = computed(() =>
  isHorizontal.value ? $t('info.resolution.size169') : $t('info.resolution.size916'),
)
const videoDirStyle = computed(() => ({
  horizontal: isHorizontal.value,
  vertical: isVertical.value,
}))

const video = ref(null)
watch(onFileInput, async (v) => {
  if (v) {
    try {
      await startUpload(video)
    } catch (e) {
      if (e instanceof VideoLengthOverlimitError) {
        emits('videoOverlimit')
      } else {
        emits('uploadFail', e.message)
      }
    }
  }
})

function onVideoFile(evt) {
  addVideoFile(evt.target.files[0], video)
}

function onImageFile(evt) {
  const files = evt.target.files
  if (files.length > 0) {
    addImageFile(files)
  }
}

const { $confirm } = usePopupDialogStore()
function cancel(id) {
  $confirm({
    title: $t('title.cancelUpload'),
    content: $t('content.cancelUpload'),
    confirm: () => {
      cancelUpload()
      removeUploadFile(id)
    },
    cancel: () => {},
  }).open()
}
</script>

<style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.type-switch {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;

  .switch {
    padding: 0 1rem;
    border: 0.0625rem solid rgb(var(--v-theme-primary));
    border-radius: 0.625rem;
  }
}

.video-input {
  width: 100%;
  display: flex;
  flex-direction: column;
  position: relative;

  .file {
    align-self: center;
    border-radius: 0.625rem;
    position: relative;
    margin-bottom: 0;

    &.horizontal {
      width: 100%;
      height: calc((100vw - 2rem) * 0.5625);
    }
    &.vertical {
      width: 10.3125rem;
      height: 18.33rem;
    }

    .reupload {
      width: 100%;
      height: 100%;
      border: 0.0625rem solid rgb(var(--v-theme-primary));
      border-radius: inherit;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;

      input {
        display: none;
      }
    }

    .upload-info {
      height: 100%;
      border-radius: inherit;

      video {
        width: 100%;
        height: 100%;
        object-fit: contain;
        border-radius: inherit;
      }

      .slice-mask {
        height: 100%;
        width: 100%;
        border-radius: inherit;
        background: linear-gradient(180deg, rgba(249, 94, 14, 0.2) 0%, rgba(231, 23, 179, 0.2) 100%);
        backdrop-filter: blur(0.25rem);
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }

  .close,
  .cancel {
    position: absolute;
    top: 1.75rem;
    right: 0.375rem;
  }
}

.image-input {
  width: 100%;
  display: flex;
  flex-direction: column;

  .image-container {
    height: 18.375rem;
    display: flex;
    overflow-y: hidden;

    .file {
      width: 10.25rem;
      height: 100%;
      border-radius: 0.625rem;
      position: relative;
      flex-shrink: 0;

      img {
        width: 100%;
        height: 100%;
        object-fit: contain;
        border-radius: inherit;
      }

      .index {
        width: fit-content;
        position: absolute;
        top: 0.625rem;
        left: 0.375rem;
      }

      .close {
        position: absolute;
        top: 0.5rem;
        right: 0.375rem;
      }

      .handle {
        position: absolute;
        bottom: 0.5rem;
        right: 0.625rem;
        user-select: none;
        cursor: grab;
      }
    }

    .add {
      width: 10.25rem;
      height: 100%;
      border: 0.125rem solid rgba(215, 215, 215, 0.4);
      border-radius: 0.625rem;
      position: relative;
      flex-shrink: 0;

      &::before,
      &::after {
        content: '';
        border-radius: 0.1875rem;
        background: #888;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }

      &::before {
        width: 2.5rem;
        height: 0.1875rem;
      }
      &::after {
        height: 2.5rem;
        width: 0.1875rem;
      }

      input {
        display: none;
      }
    }
  }
}

.desktop {
  .video-input {
    .file.horizontal {
      height: calc((var(--desktop-main-width) - 2rem) * 0.5625);
    }
  }

  .image-input {
    .image-container {
      &::-webkit-scrollbar {
        height: 0.5rem;
        display: block;
      }
      &::-webkit-scrollbar-thumb {
        background: var(--color-primary-divider, rgba(215, 215, 215, 0.4));
        border-radius: 0.25rem;
      }
    }
  }
}
</style>
